package server

import (
	"distributed/message"
	"distributed/parser"
	"fmt"
)

var (
	taskChan chan message.ReptileReq
)

type Worker struct{}

func (w *Worker) Receiver(req message.ReptileResult, rep *message.ReptileResp) error {
	//fmt.Println("[ Receiver ]", req)
	switch req.Function {
	case parser.HackRecent:
		if err := storeRecord(req, parser.HackRecent); err != nil {
			fmt.Println("[ Receiver ] error: ", err)
			rep.Status = 300
			rep.Result = "failed"
			return nil
		}
	case parser.Net163HomeHead:
		go func(r *[]message.BriefInformation) {
			for _, v := range *r {
				fmt.Println("[ taskChan <- Net163HomeHead ] ", v.URL)
				taskChan <- message.ReptileReq{
					Method:   "GET",
					URL:      v.URL,
					Function: parser.Net163WarParser,
				}
			}
		}(req.ParserResult)
		if err := storeRecord(req, parser.Net163HomeHead); err != nil {
			fmt.Println("[ Receiver Net163HomeHead ] error: ", err)
			rep.Status = 300
			rep.Result = "failed"
			return nil
		}
	case parser.Net163WarParser:
		fmt.Println("[ Receiver Net163WarParser ] ", req.URL)
		if err := storeRecord(req, parser.Net163WarParser); err != nil {
			fmt.Println("[ Receiver Net163WarParser ] error: ", err)
			rep.Status = 300
			rep.Result = "failed"
			return nil
		}
	case parser.HotPageParser:
		if req.NextPageUrl != nil {
			fmt.Printf("[ req.NextPageUrl ] %v\n", req.NextPageUrl)
			taskChan <- message.ReptileReq{
				Method:   "GET",
				URL:      *req.NextPageUrl,
				Function: parser.HotPageParser,
			}
		}

		for _, v := range *req.ParserResult {
			taskChan <- message.ReptileReq{
				Method:   "GET",
				URL:      v.URL,
				Function: parser.SongIDParser,
			}
		}

		if err := storeRecord(req, parser.HotPageParser); err != nil {
			fmt.Println("[ Receiver HotPageParser ] error: ", err)
			rep.Status = 300
			rep.Result = "failed"
			return nil
		}
	case parser.SongIDParser:
		for _, v := range *req.ParserResult {
			fmt.Printf("[ case parser.SongIDParser ] song_id: %v\n", v.URL)
			taskChan <- message.ReptileReq{
				Method: "POST",
				// song_id
				URL:      v.URL,
				Function: parser.CommentApiParser,
				Limit:    20,
				Offset:   0,
			}
		}
		rep.Status = 200
		rep.Result = "success"
		return nil
	case parser.SongDetailParser:
		if err := storeRecord(req, parser.SongDetailParser); err != nil {
			fmt.Println("[ Receiver SongDetailParser ] error: ", err)
			rep.Status = 300
			rep.Result = "failed"
			return nil
		}
		rep.Status = 200
		rep.Result = "success"
		return nil
	case parser.CommentApiParser:
		fmt.Printf("[ case parser.CommentApiParser ] song_id: %v\n", req.URL)
		if req.ParserResult != nil {
			//if !req.Total {
			fmt.Printf("[ case parser.CommentApiParser ] taskChan <- task: %v\tlimit: %v\toffset: %v\n", req.URL, req.Limit, req.Offset+20)
			taskChan <- message.ReptileReq{
				Method: "POST",
				// song_id
				URL:      req.URL,
				Function: parser.CommentApiParser,
				Limit:    req.Limit,
				Offset:   req.Offset + 20,
			}
			//}

			//fmt.Printf("[ case parser.CommentApiParser ] comment: %#v\n", req.ParserResult)
			if err := storeRecord(req, parser.CommentApiParser); err != nil {
				fmt.Println("[ Receiver CommentApiParser ] error: ", err)
				rep.Status = 300
				rep.Result = "failed"
				return nil
			}
		}
	}
	rep.Status = 200
	rep.HttpStatus = 200
	rep.Result = "success"
	return nil

}

func (w *Worker) PullTask(req message.ReptileReq, resp *message.ReptileReq) error {
	readyChan := make(chan message.ReptileReq)
	taskReadyChan <- readyChan
	task := <-readyChan
	close(readyChan)
	fmt.Printf("[ PullTask ] task: %v\n", task)
	resp.URL = task.URL
	resp.Method = task.Method
	resp.Offset = task.Offset
	resp.Limit = task.Limit
	resp.Function = task.Function
	return nil
}

//func (w *Worker) Ready(req message.ReptileReq, rep *message.ReptileResp) error {
//	// todo: go func and make a chan to scheduler
//	if req.URL == "" {
//		rep.Status = 500
//		rep.Result = "url is ''"
//		return nil
//	}
//	threadReady <- req
//	rep.Status = 200
//	rep.Result = "success"
//	return nil
//}

//func workerClient(url string) (wc *WorkerClient, err error) {
//	client, err := rpc.DialHTTP("tcp", url)
//	if err != nil {
//		// fmt.Printf("[ workerClient ] error: %v\n", err)
//		return nil, err
//	}
//	return &WorkerClient{
//		Client:   client,
//		url:      url,
//		lastTime: time.Now().Add(-PushSpeed * 2),
//	}, nil
//}
//
//var (
//	ERRNoClient = errors.New("no worker client")
//)
//
//func getClient() (*WorkerClient, error) {
//	for key, v := range workerClients {
//		if time.Now().Sub(v.lastTime) > PushSpeed {
//			fmt.Println("[ getClient ] key: ", key)
//			v.lastTime = time.Now()
//			return v, nil
//		}
//	}
//	return nil, ERRNoClient
//}
